package com.sirui.x.learn_security;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@SpringBootApplication
@EnableMethodSecurity
public class LearnSecurityApplication {

	public static void main(String[] args) {
		SpringApplication.run(LearnSecurityApplication.class, args);
	}

	
	@Bean
	SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
		
		http.csrf(csrf -> csrf.disable());

		http.authorizeHttpRequests((requests) -> {
			requests.antMatchers("/security/test").denyAll();
			requests.anyRequest().authenticated();
		});
		
		http.formLogin(formloginCustom -> {
			formloginCustom.loginPage("/auth1/login").permitAll();
			formloginCustom.loginProcessingUrl("/auth1/loginpost").permitAll();
			// 登录成功或者失败的josn，替代重定向
			formloginCustom.failureHandler((request, response, exception) -> {
				writeResp(request, response, "用户名和密码错误");
			}).successHandler((request, response, authentication) -> {
				writeResp(request, response, "登录成功");
			});
		});
		
		http.logout(logoutCustom -> {
			//登出接口的json 替代重定向
			logoutCustom.logoutSuccessHandler((request, response, authentication) -> {
				writeResp(request, response, "登出成功");
			});
		});
		
		http.exceptionHandling(exceptionHandlCustom -> {
			// 请求未登录json替代重定向
			exceptionHandlCustom.authenticationEntryPoint((request, response, authException) -> {
				writeResp(request, response, "未登录");
			});
			//请求未授权json替代重定向
			exceptionHandlCustom.accessDeniedHandler((request, response, accessDeniedException) -> {
				writeResp(request, response, "权限不足");
			});
		});
		
		http.sessionManagement(sessionMgtCustom -> {
//			sessionMgtCustom.sessionCreationPolicy(SessionCreationPolicy.STATELESS).maximumSessions(1);
		});
		
		return http.build();
	}

	private void writeResp(HttpServletRequest request, HttpServletResponse response, String msg) throws IOException{
		response.setContentType("application/json;charset=UTF-8");
		
		try(PrintWriter writer = response.getWriter()){
			writer.println(msg);
		}
	}
	
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

}
